// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(
    all(not(debug_assertions), target_os = "windows"),
    windows_subsystem = "windows"
)]

// use std::fs;
use tauri_plugin_dialog::DialogExt;
use std::fs;
use serde::{Deserialize, Serialize};
use serde_yaml;
use serde_json;
use regex::Regex;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TreeNode {
    pub id: String,
    pub label: String,
    pub display_name: String,
    pub x_descriptor_count: usize,
    pub children_descriptor_count: usize,
    pub hidden: bool,
    pub x_descriptors: Vec<String>,
    pub children: Option<Vec<TreeNode>>,
    pub description: Option<String>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SpecDescriptor {
    pub path: String,
    #[serde(rename = "displayName", skip_serializing_if = "Option::is_none")]
    pub display_name: Option<String>,
    #[serde(rename = "x-descriptors")]
    pub x_descriptors: Vec<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
enum VersionStability {
    Alpha,
    Beta,
    Stable,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ParseCrdResult {
    pub tree_data: Vec<TreeNode>,
    pub selected_version: Option<String>,
}

#[derive(Debug, Clone)]
struct CrdVersion {
    major: u32,
    minor: Option<u32>,
    stability: VersionStability,
    stability_version: Option<u32>,
    #[allow(dead_code)] // 添加允许未使用的注解
    original: String,
}

fn tree_to_descriptors(nodes: &[TreeNode], path: String) -> Vec<SpecDescriptor> {
    let mut descriptors = Vec::new();
    
    for node in nodes {
        let current_path = if path.is_empty() {
            node.label.clone()
        } else {
            format!("{}.{}", path, node.label)
        };
        
        if !node.x_descriptors.is_empty() {
            descriptors.push(SpecDescriptor {
                path: current_path.clone(),
                // 如果display_name不为空，总是包含displayName字段
                display_name: if !node.display_name.is_empty() { 
                    Some(node.display_name.clone()) 
                } else { 
                    None 
                },
                x_descriptors: node.x_descriptors.clone(),
            });
        }
        
        if let Some(children) = &node.children {
            descriptors.extend(tree_to_descriptors(children, current_path));
        }
    }
    
    descriptors
}

fn update_tree_with_descriptors(nodes: &mut [TreeNode], descriptors: &[SpecDescriptor], path: String) {
    for node in nodes {
        let current_path = if path.is_empty() {
            node.label.clone()
        } else {
            format!("{}.{}", path, node.label)
        };
        
        // 查找对应的描述符
        if let Some(desc) = descriptors.iter().find(|d| d.path == current_path) {
            // 有配置：应用描述符配置
            node.x_descriptors = desc.x_descriptors.clone();
            node.x_descriptor_count = desc.x_descriptors.len();
            node.hidden = desc.x_descriptors.contains(&"urn:alm:descriptor:com.tectonic.ui:hidden".to_string());
            
            // 更新display_name字段：如果descriptor中有displayName则使用，否则使用默认值（label）
            if let Some(display_name) = &desc.display_name {
                node.display_name = display_name.clone();
            } else {
                // 如果descriptor中没有指定displayName，使用默认值
                node.display_name = node.label.clone();
            }
        } else {
            // 没有配置：清空字段属性
            node.x_descriptors.clear();
            node.x_descriptor_count = 0;
            node.hidden = false;
            node.display_name = node.label.clone(); // 重置为默认值
        }
        
        if let Some(children) = &mut node.children {
            update_tree_with_descriptors(children, descriptors, current_path);
        }
    }
}

fn update_children_descriptor_count(nodes: &mut [TreeNode]) {
    for node in nodes {
        let mut count = 0;
        
        if let Some(children) = &mut node.children {
            // 递归更新子节点
            update_children_descriptor_count(children);
            
            // 统计子节点中有 x-descriptors 的数量
            for child in children.iter() {
                if !child.x_descriptors.is_empty() {
                    count += 1;
                }
                // 同时加上子节点的子字段数量
                count += child.children_descriptor_count;
            }
        }
        
        node.children_descriptor_count = count;
    }
}

fn extract_fields(schema: &serde_yaml::Value, path: Vec<String>) -> Vec<TreeNode> {
    extract_fields_with_parent(schema, path, None)
}

fn extract_fields_with_parent(schema: &serde_yaml::Value, path: Vec<String>, parent_context: Option<(&str, &str)>) -> Vec<TreeNode> {
    let mut nodes = Vec::new();
    if let Some(props) = schema.get("properties") {
        if let Some(map) = props.as_mapping() {
            for (key, value) in map.iter() {
                let key_str = key.as_str().unwrap_or("").to_string();
                let mut new_path = path.clone();
                new_path.push(key_str.clone());
                let x_descriptors = value.get("x-descriptors")
                    .and_then(|v| v.as_sequence())
                    .map(|seq| seq.iter().filter_map(|x| x.as_str().map(|s| s.to_string())).collect::<Vec<_>>())
                    .unwrap_or_default();
                let hidden = x_descriptors.iter().any(|x| x == "urn:alm:descriptor:com.tectonic.ui:hidden");
                
                let description = value.get("description")
                    .and_then(|v| v.as_str())
                    .map(|s| s.to_string());
                
                // 检查是否是引用字段（字段名为name且父节点只有一个name字段）
                let is_reference_field = key_str == "name" && 
                    parent_context.is_some() && 
                    map.len() == 1; // 父节点只有一个字段
                
                // 根据引用字段规则生成displayName
                let display_name = if is_reference_field {
                    if let Some((parent_label, _)) = parent_context {
                        format!("{} {}", parent_label, key_str)
                    } else {
                        key_str.clone()
                    }
                } else {
                    key_str.clone()
                };
                
                // 为当前字段准备父节点上下文信息
                let current_context = Some((key_str.as_str(), description.as_deref().unwrap_or("")));
                let children = extract_fields_with_parent(value, new_path.clone(), current_context);
                
                nodes.push(TreeNode {
                    id: new_path.join("."),
                    label: key_str.clone(),
                    display_name,
                    x_descriptor_count: x_descriptors.len(),
                    children_descriptor_count: 0,
                    hidden,
                    x_descriptors,
                    children: if children.is_empty() { None } else { Some(children) },
                    description,
                });
            }
        }
    }
    nodes
}

// 解析版本字符串
fn parse_version(version_str: &str) -> Result<CrdVersion, String> {
    let re = Regex::new(r"^v(\d+)(?:\.(\d+))?(?:(alpha|beta)(\d+)?)?$")
        .map_err(|e| format!("正则表达式错误: {}", e))?;
    
    if let Some(captures) = re.captures(version_str) {
        let major = captures.get(1)
            .unwrap()
            .as_str()
            .parse::<u32>()
            .map_err(|e| format!("解析主版本号失败: {}", e))?;
        
        let minor = captures.get(2)
            .map(|m| m.as_str().parse::<u32>())
            .transpose()
            .map_err(|e| format!("解析次版本号失败: {}", e))?;
        
        let (stability, stability_version) = match captures.get(3) {
            Some(stability_match) => {
                let stability = match stability_match.as_str() {
                    "alpha" => VersionStability::Alpha,
                    "beta" => VersionStability::Beta,
                    _ => return Err(format!("未知的稳定性标识: {}", stability_match.as_str())),
                };
                
                let stability_version = captures.get(4)
                    .map(|m| m.as_str().parse::<u32>())
                    .transpose()
                    .map_err(|e| format!("解析稳定性版本号失败: {}", e))?;
                
                (stability, stability_version)
            }
            None => (VersionStability::Stable, None),
        };
        
        Ok(CrdVersion {
            major,
            minor,
            stability,
            stability_version,
            original: version_str.to_string(),
        })
    } else {
        Err(format!("无效的版本格式: {}", version_str))
    }
}

// 比较两个版本，返回较新的版本
fn compare_versions(a: &CrdVersion, b: &CrdVersion) -> std::cmp::Ordering {
    use std::cmp::Ordering;
    
    // 首先比较主版本号
    match a.major.cmp(&b.major) {
        Ordering::Equal => {}
        other => return other,
    }
    
    // 比较次版本号
    match (a.minor, b.minor) {
        (Some(a_minor), Some(b_minor)) => {
            match a_minor.cmp(&b_minor) {
                Ordering::Equal => {}
                other => return other,
            }
        }
        (Some(_), None) => return Ordering::Greater,
        (None, Some(_)) => return Ordering::Less,
        (None, None) => {}
    }
    
    // 比较稳定性级别 (Stable > Beta > Alpha)
    match a.stability.cmp(&b.stability) {
        Ordering::Equal => {}
        other => return other,
    }
    
    // 比较稳定性版本号
    match (a.stability_version, b.stability_version) {
        (Some(a_stab), Some(b_stab)) => a_stab.cmp(&b_stab),
        (Some(_), None) => Ordering::Greater,
        (None, Some(_)) => Ordering::Less,
        (None, None) => Ordering::Equal,
    }
}

// 从版本列表中选择最新版本
fn select_latest_version(versions: &[serde_yaml::Value]) -> Option<&serde_yaml::Value> {
    let mut best_version: Option<(&serde_yaml::Value, CrdVersion)> = None;
    
    for version in versions {
        if let Some(name) = version.get("name").and_then(|n| n.as_str()) {
            if let Ok(parsed_version) = parse_version(name) {
                match &best_version {
                    None => {
                        best_version = Some((version, parsed_version));
                    }
                    Some((_, current_best)) => {
                        if compare_versions(&parsed_version, current_best) == std::cmp::Ordering::Greater {
                            best_version = Some((version, parsed_version));
                        }
                    }
                }
            }
        }
    }
    
    best_version.map(|(version, _)| version)
}

#[tauri::command]
fn parse_crd(yaml_text: String) -> Result<ParseCrdResult, String> {
    let doc: serde_yaml::Value = serde_yaml::from_str(&yaml_text).map_err(|e| e.to_string())?;
    
    let mut schema = None;
    let mut selected_version = None;
    
    if let Some(spec) = doc.get("spec") {
        if let Some(versions) = spec.get("versions").and_then(|v| v.as_sequence()) {
            // 选择最新版本而不是第一个版本
            if let Some(latest_version) = select_latest_version(versions) {
                schema = latest_version.get("schema").and_then(|s| s.get("openAPIV3Schema"));
                
                // 记录选择的版本信息
                if let Some(version_name) = latest_version.get("name").and_then(|n| n.as_str()) {
                    selected_version = Some(version_name.to_string());
                }
            }
        } else if let Some(validation) = spec.get("validation") {
            schema = validation.get("openAPIV3Schema");
            selected_version = Some("legacy".to_string());
        }
    }
    
    let tree_data = if let Some(schema) = schema {
        if let Some(spec_field) = schema.get("properties").and_then(|p| p.get("spec")) {
            extract_fields(spec_field, vec![])
        } else {
            // 如果没有找到spec字段，返回空数组而不是错误
            vec![]
        }
    } else {
        // 如果没有找到schema，返回空数组而不是错误
        vec![]
    };
    
    Ok(ParseCrdResult {
        tree_data,
        selected_version,
    })
}

#[tauri::command]
fn tree_to_yaml_descriptors(tree_data: Vec<TreeNode>) -> Result<String, String> {
    let descriptors = tree_to_descriptors(&tree_data, String::new());
    
    if descriptors.is_empty() {
        return Ok("specDescriptors: []".to_string());
    }
    
    let mut result = "specDescriptors:\n".to_string();
    
    for descriptor in &descriptors {
        result.push_str(&format!("  - path: {}\n", descriptor.path));
        // 如果有displayName就输出
        if let Some(display_name) = &descriptor.display_name {
            result.push_str(&format!("    displayName: {}\n", display_name));
        }
        result.push_str("    x-descriptors:\n");
        for x_desc in &descriptor.x_descriptors {
            result.push_str(&format!("      - '{}'\n", x_desc));
        }
    }
    
    Ok(result)
}

#[tauri::command]
fn parse_yaml_descriptors(yaml_content: String) -> Result<Vec<SpecDescriptor>, String> {
    // 简单的YAML解析，处理specDescriptors格式
    let lines: Vec<&str> = yaml_content.lines().collect();
    let mut descriptors = Vec::new();
    let mut current_descriptor: Option<SpecDescriptor> = None;
    let mut in_x_descriptors = false;
    
    for line in lines {
        let trimmed = line.trim();
        
        if trimmed.starts_with("- path:") {
            // 保存之前的描述符
            if let Some(desc) = current_descriptor.take() {
                descriptors.push(desc);
            }
            
            let path = trimmed.replace("- path:", "").trim().to_string();
            current_descriptor = Some(SpecDescriptor {
                path,
                display_name: None,
                x_descriptors: Vec::new(),
            });
            in_x_descriptors = false;
        } else if trimmed.starts_with("displayName:") {
            if let Some(ref mut desc) = current_descriptor {
                desc.display_name = Some(trimmed.replace("displayName:", "").trim().to_string());
            }
        } else if trimmed == "x-descriptors:" {
            in_x_descriptors = true;
        } else if in_x_descriptors && trimmed.starts_with("- '") {
            if let Some(ref mut desc) = current_descriptor {
                let x_desc = trimmed.replace("- '", "").replace("'", "");
                desc.x_descriptors.push(x_desc);
            }
        }
    }
    
    // 保存最后一个描述符
    if let Some(desc) = current_descriptor {
        descriptors.push(desc);
    }
    
    Ok(descriptors)
}

#[tauri::command]
fn apply_descriptors_to_tree(mut tree_data: Vec<TreeNode>, descriptors: Vec<SpecDescriptor>) -> Result<Vec<TreeNode>, String> {
    update_tree_with_descriptors(&mut tree_data, &descriptors, String::new());
    // 更新子字段描述符计数
    update_children_descriptor_count(&mut tree_data);
    Ok(tree_data)
}

#[tauri::command]
fn update_children_descriptor_counts(mut tree_data: Vec<TreeNode>) -> Result<Vec<TreeNode>, String> {
    update_children_descriptor_count(&mut tree_data);
    Ok(tree_data)
}

// 清理描述文本：去掉换行，句号后保留一个空格
fn clean_description_text(text: &str) -> String {
    // 先去掉所有换行符和多余的空白字符
    let mut cleaned = text.replace('\n', " ").replace('\r', " ");
    
    // 将多个连续空格替换为单个空格
    while cleaned.contains("  ") {
        cleaned = cleaned.replace("  ", " ");
    }
    
    // 处理句号后的空格：确保句号后只有一个空格
    cleaned = cleaned.replace(". ", ". "); // 先标准化
    cleaned = cleaned.replace(".", ". "); // 确保句号后有空格
    
    // 再次清理多余空格
    while cleaned.contains("  ") {
        cleaned = cleaned.replace("  ", " ");
    }
    
    // 去掉首尾空格
    cleaned.trim().to_string()
}

#[tauri::command]
fn validate_yaml(yaml_text: String) -> Result<(), String> {
    serde_yaml::from_str::<serde_yaml::Value>(&yaml_text).map_err(|e| e.to_string())?;
    Ok(())
}

#[tauri::command]
fn apply_sample_to_fields(crd_text: String, sample_text: String) -> Result<Vec<TreeNode>, String> {
    // 1. 解析CRD获取字段结构
    let parse_result = parse_crd(crd_text.clone())
        .map_err(|e| format!("CRD解析失败: {}", e))?;
    
    let mut tree_data = parse_result.tree_data;
    
    if tree_data.is_empty() {
        return Ok(vec![]); // 如果没有字段定义，返回空数组而不是错误
    }
    
    // 2. 解析Sample YAML
    let sample_doc: serde_yaml::Value = serde_yaml::from_str(&sample_text)
        .map_err(|e| format!("Sample YAML格式错误: {}", e))?;
    
    // 3. 从sample中提取spec字段
    let spec_fields = sample_doc.get("spec")
        .ok_or_else(|| "Sample YAML中未找到spec字段，请确保Sample包含spec部分".to_string())?;
    
    // 4. 分析sample的spec字段，自动生成x-descriptors
    apply_sample_analysis(&mut tree_data, spec_fields, "");
    
    // 5. 更新子字段描述符计数
    update_children_descriptor_count(&mut tree_data);
    
    Ok(tree_data)
}

fn apply_sample_analysis(nodes: &mut [TreeNode], sample_spec: &serde_yaml::Value, path_prefix: &str) {
    apply_sample_analysis_with_parent(nodes, sample_spec, path_prefix, None);
}

fn apply_sample_analysis_with_parent(nodes: &mut [TreeNode], sample_spec: &serde_yaml::Value, path_prefix: &str, parent_info: Option<(&str, &str)>) {
    for node in nodes {
        let current_path = if path_prefix.is_empty() {
            node.label.clone()
        } else {
            format!("{}.{}", path_prefix, node.label)
        };
        
        // 检查是否是引用字段并设置displayName
        let is_reference_field = node.label == "name" && parent_info.is_some();
        if is_reference_field {
            if let Some((parent_label, _)) = parent_info {
                node.display_name = format!("{} {}", parent_label, node.label);
            }
        }
        // 如果不是引用字段，不在sample导入时自动设置display_name，保持原有值
        
        // 检查当前字段在sample中是否存在
        if let Some(field_value) = get_nested_field(sample_spec, &current_path) {
            // 根据字段值的类型和内容自动推断x-descriptors
            let mut auto_descriptors = Vec::new();
            
            // 检查字段描述是否包含Deprecated
            if node.label.to_lowercase().contains("deprecated") {
                auto_descriptors.push("urn:alm:descriptor:com.tectonic.ui:hidden".to_string());
            }
            
            // 根据字段值类型推断合适的descriptor
            match field_value {
                serde_yaml::Value::String(s) => {
                    // 移除URL自动识别为link的逻辑，所有字符串都作为基础输入组件处理
                    if s.contains("password") || s.contains("secret") || s.contains("token") {
                        auto_descriptors.push("urn:alm:descriptor:com.tectonic.ui:password".to_string());
                    } else if s.len() > 100 {
                        auto_descriptors.push("urn:alm:descriptor:com.tectonic.ui:text".to_string());
                    } else {
                        auto_descriptors.push("urn:alm:descriptor:com.tectonic.ui:text".to_string());
                    }
                }
                serde_yaml::Value::Number(n) => {
                    if n.is_i64() {
                        auto_descriptors.push("urn:alm:descriptor:com.tectonic.ui:number".to_string());
                    }
                }
                serde_yaml::Value::Bool(_) => {
                    auto_descriptors.push("urn:alm:descriptor:com.tectonic.ui:booleanSwitch".to_string());
                }
                serde_yaml::Value::Sequence(_) => {
                    auto_descriptors.push("urn:alm:descriptor:com.tectonic.ui:arrayFieldGroup".to_string());
                }
                serde_yaml::Value::Mapping(_) => {
                    // 对象类型，不添加通用的fieldGroup描述符
                    // fieldGroup将在后续根据父子关系自动添加
                }
                _ => {}
            }
            
            // 合并现有的x-descriptors和自动生成的descriptors
            let mut combined_descriptors = node.x_descriptors.clone();
            for desc in auto_descriptors {
                if !combined_descriptors.contains(&desc) {
                    combined_descriptors.push(desc);
                }
            }
            
            node.x_descriptors = combined_descriptors;
            node.x_descriptor_count = node.x_descriptors.len();
            node.hidden = node.x_descriptors.contains(&"urn:alm:descriptor:com.tectonic.ui:hidden".to_string());
        } else {
            // 即使字段在 sample 中不存在，也要检查是否需要根据字段名称添加描述符
            if node.label.to_lowercase().contains("deprecated") {
                let hidden_descriptor = "urn:alm:descriptor:com.tectonic.ui:hidden".to_string();
                if !node.x_descriptors.contains(&hidden_descriptor) {
                    node.x_descriptors.push(hidden_descriptor);
                    node.x_descriptor_count = node.x_descriptors.len();
                    node.hidden = true;
                }
            }
        }
        
        // 递归处理子节点，传递当前节点作为父节点信息
        if let Some(children) = &mut node.children {
            let current_info = Some((node.label.as_str(), node.description.as_deref().unwrap_or("")));
            apply_sample_analysis_with_parent(children, sample_spec, &current_path, current_info);
        }
    }
}

fn get_nested_field<'a>(value: &'a serde_yaml::Value, path: &str) -> Option<&'a serde_yaml::Value> {
    // 分解路径，跳过空字符串
    let parts: Vec<&str> = path.split('.').filter(|p| !p.is_empty()).collect();
    let mut current = value;
    
    for part in parts {
        match current {
            serde_yaml::Value::Mapping(map) => {
                // 尝试多种可能的键格式
                let possible_keys = vec![
                    serde_yaml::Value::String(part.to_string()),
                    serde_yaml::Value::String(part.to_lowercase()),
                    serde_yaml::Value::String(part.to_uppercase()),
                ];
                
                let mut found = false;
                for key in possible_keys {
                    if let Some(next) = map.get(&key) {
                        current = next;
                        found = true;
                        break;
                    }
                }
                
                if !found {
                    return None;
                }
            }
            _ => return None,
        }
    }
    
    Some(current)
}

#[tauri::command]
fn add_descriptions_to_leaf_nodes(mut tree_data: Vec<TreeNode>) -> Result<Vec<TreeNode>, String> {
    fn process_nodes(nodes: &mut [TreeNode]) {
        process_nodes_with_parent(nodes, None);
    }
    
    fn process_nodes_with_parent(nodes: &mut [TreeNode], parent_info: Option<(&str, &str)>) {
        for node in nodes {
            // 检查是否为叶子节点（没有子节点）
            let is_leaf = node.children.is_none() || node.children.as_ref().unwrap().is_empty();
            
            if is_leaf {
                // 检查是否有属性且没有hidden描述符
                let has_descriptors = !node.x_descriptors.is_empty();
                let is_not_hidden = !node.x_descriptors.contains(&"urn:alm:descriptor:com.tectonic.ui:hidden".to_string());
                
                if has_descriptors && is_not_hidden {
                    // 检查是否是引用字段（字段名为name且父节点存在）
                    let is_reference_field = node.label == "name" && parent_info.is_some();
                    
                    // 为引用字段设置特殊的displayName
                    if is_reference_field {
                        if let Some((parent_label, _)) = parent_info {
                            node.display_name = format!("{} {}", parent_label, node.label);
                        }
                    } else if node.display_name.is_empty() || node.display_name == node.label {
                        // 设置默认的displayName（如果还没有设置或等于label）
                        node.display_name = node.label.clone();
                    }
                    
                    // 决定使用哪个描述：引用字段使用父节点描述，否则使用自己的描述
                    let description_to_use = if is_reference_field {
                        if let Some((_, parent_description)) = parent_info {
                            if !parent_description.is_empty() {
                                Some(parent_description.to_string())
                            } else {
                                node.description.clone()
                            }
                        } else {
                            node.description.clone()
                        }
                    } else {
                        node.description.clone()
                    };
                    
                    // 如果有描述信息，添加描述符
                    if let Some(description) = description_to_use {
                        // 处理描述文本：去掉换行，句号后保留一个空格
                        let cleaned_description = clean_description_text(&description);
                        let desc_en = format!("urn:alm:descriptor:description:en:{}", cleaned_description);
                        let desc_zh = format!("urn:alm:descriptor:description:zh:{}", cleaned_description);
                        
                        // 检查是否已存在相同的描述符，避免重复添加
                        if !node.x_descriptors.iter().any(|d| d.starts_with("urn:alm:descriptor:description:en:")) {
                            node.x_descriptors.push(desc_en);
                        }
                        if !node.x_descriptors.iter().any(|d| d.starts_with("urn:alm:descriptor:description:zh:")) {
                            node.x_descriptors.push(desc_zh);
                        }
                        
                        // 更新描述符数量
                        node.x_descriptor_count = node.x_descriptors.len();
                    }
                }
            } else {
                // 如果不是叶子节点，递归处理子节点，传递当前节点作为父节点信息
                if let Some(children) = &mut node.children {
                    let current_info = Some((node.label.as_str(), node.description.as_deref().unwrap_or("")));
                    process_nodes_with_parent(children, current_info);
                }
            }
        }
    }
    
    process_nodes(&mut tree_data);
    
    // 更新子字段描述符计数
    update_children_descriptor_count(&mut tree_data);
    
    Ok(tree_data)
}

#[tauri::command]
async fn save_file_dialog(app_handle: tauri::AppHandle, content: String, default_file_name: String) -> Result<String, String> {
    let (tx, rx) = std::sync::mpsc::channel();
    
    app_handle.dialog().file()
        .add_filter("YAML", &["yaml", "yml"])
        .set_file_name(&default_file_name)
        .save_file(move |file_path| {
            if let Some(path) = file_path {
                if let Some(real_path) = path.as_path() {
                    match fs::write(real_path, content) {
                        Ok(_) => tx.send(Ok("success".to_string())).ok(),
                        Err(e) => tx.send(Err(format!("Failed to write file: {}", e))).ok(),
                    };
                } else {
                    tx.send(Err("Invalid file path".to_string())).ok();
                }
            } else {
                tx.send(Ok("cancelled".to_string())).ok();
            }
        });
    
    rx.recv().unwrap_or_else(|_| Err("Dialog error".to_string()))
}

#[tauri::command]
fn propagate_field_dependency(tree_data: &str) -> Result<String, String> {
    let mut tree: TreeNode = serde_json::from_str(tree_data)
        .map_err(|e| format!("Failed to parse tree data: {}", e))?;
    
    propagate_field_dependency_recursive(&mut tree);
    
    serde_json::to_string(&tree)
        .map_err(|e| format!("Failed to serialize tree: {}", e))
}

fn propagate_field_dependency_recursive(node: &mut TreeNode) {
    let field_dependency_prefix = "urn:alm:descriptor:com.tectonic.ui:fieldDependency";
    let object_descriptor = "urn:alm:descriptor:com.tectonic.ui:object";
    
    // 1. 处理fieldDependency传播（传播给所有后代叶子节点）
    let field_dependency_descriptors: Vec<String> = node.x_descriptors
        .iter()
        .filter(|desc| desc.starts_with(field_dependency_prefix))
        .cloned()
        .collect();
    
    if !field_dependency_descriptors.is_empty() {
        propagate_to_all_descendants(&mut node.children, &field_dependency_descriptors);
    }
    
    // 2. 处理object描述符传播（传播fieldGroup给叶子节点）
    if node.x_descriptors.contains(&object_descriptor.to_string()) {
        let field_group_descriptor = format!("urn:alm:descriptor:com.tectonic.ui:fieldGroup:{}", node.label);
        propagate_field_group_to_leaves(&mut node.children, &field_group_descriptor, node.label.as_str());
    }
    
    // 3. 递归处理子字段
    if let Some(children) = &mut node.children {
        for child in children.iter_mut() {
            propagate_field_dependency_recursive(child);
        }
    }
}

// 新增辅助函数：将fieldDependency传播到所有后代节点
fn propagate_to_all_descendants(children: &mut Option<Vec<TreeNode>>, field_dependency_descriptors: &[String]) {
    if let Some(children_vec) = children {
        for child in children_vec.iter_mut() {
            // 只传播给有描述符配置的节点
            if child.x_descriptor_count > 0 {
                for field_dep in field_dependency_descriptors {
                    // 检查子字段是否已经有这个fieldDependency描述符
                    if !child.x_descriptors.contains(field_dep) {
                        child.x_descriptors.push(field_dep.clone());
                        child.x_descriptor_count = child.x_descriptors.len();
                    }
                }
            }
            
            // 递归传播到更深层的后代节点
            propagate_to_all_descendants(&mut child.children, field_dependency_descriptors);
        }
    }
}

// 新增辅助函数：将fieldGroup传播到叶子节点，但不越过有object描述符的中间节点
fn propagate_field_group_to_leaves(children: &mut Option<Vec<TreeNode>>, field_group_descriptor: &str, source_label: &str) {
    if let Some(children_vec) = children {
        for child in children_vec.iter_mut() {
            let has_object = child.x_descriptors.contains(&"urn:alm:descriptor:com.tectonic.ui:object".to_string());
            
            // 如果当前节点有object描述符，停止传播（它会生成自己的fieldGroup）
            if has_object {
                continue;
            }
            
            // 检查是否为叶子节点
            let is_leaf = child.children.is_none() || child.children.as_ref().unwrap().is_empty();
            
            if is_leaf && child.x_descriptor_count > 0 {
                // 移除所有现有的fieldGroup描述符
                child.x_descriptors.retain(|desc| !desc.starts_with("urn:alm:descriptor:com.tectonic.ui:fieldGroup"));
                
                // 添加新的fieldGroup描述符
                child.x_descriptors.push(field_group_descriptor.to_string());
                child.x_descriptor_count = child.x_descriptors.len();
            } else if !is_leaf {
                // 如果不是叶子节点且没有object描述符，继续向下传播
                propagate_field_group_to_leaves(&mut child.children, field_group_descriptor, source_label);
            }
        }
    }
}

#[tauri::command]
fn load_crd_from_file(crd_text: String) -> Result<ParseCrdResult, String> {
    parse_crd(crd_text)
}

#[tauri::command] 
fn save_crd_to_file(tree_data: Vec<TreeNode>) -> Result<String, String> {
    tree_to_yaml_descriptors(tree_data)
}

#[tauri::command]
fn export_yaml(tree_data: Vec<TreeNode>) -> Result<String, String> {
    tree_to_yaml_descriptors(tree_data)
}

#[tauri::command]
fn extract_fields_command(crd_text: String) -> Result<Vec<TreeNode>, String> {
    let parse_result = parse_crd(crd_text)?;
    Ok(parse_result.tree_data)
}

#[tauri::command]
fn tree_to_descriptors_command(tree_data: Vec<TreeNode>) -> Result<String, String> {
    tree_to_yaml_descriptors(tree_data)
}

#[tauri::command]
fn update_tree_with_descriptors_command(tree_data: Vec<TreeNode>, descriptors_yaml: String) -> Result<Vec<TreeNode>, String> {
    let descriptors = parse_yaml_descriptors(descriptors_yaml)?;
    apply_descriptors_to_tree(tree_data, descriptors)
}

#[tauri::command]
async fn open_file_dialog(app_handle: tauri::AppHandle) -> Result<String, String> {
    let (tx, rx) = std::sync::mpsc::channel();
    
    app_handle.dialog().file()
        .add_filter("YAML", &["yaml", "yml"])
        .add_filter("All Files", &["*"])
        .pick_file(move |file_path| {
            if let Some(path) = file_path {
                if let Some(real_path) = path.as_path() {
                    match fs::read_to_string(real_path) {
                        Ok(content) => tx.send(Ok(content)).ok(),
                        Err(e) => tx.send(Err(format!("Failed to read file: {}", e))).ok(),
                    };
                } else {
                    tx.send(Err("Invalid file path".to_string())).ok();
                }
            } else {
                tx.send(Err("Dialog cancelled".to_string())).ok();
            }
        });
    
    rx.recv().unwrap_or_else(|_| Err("Dialog error".to_string()))
}

#[tauri::command]
fn update_field_display_name(mut tree_data: Vec<TreeNode>, field_path: String, new_display_name: String) -> Result<Vec<TreeNode>, String> {
    fn update_node_display_name(nodes: &mut [TreeNode], target_path: &str, display_name: &str, current_path: &str) -> bool {
        for node in nodes {
            let node_path = if current_path.is_empty() {
                node.label.clone()
            } else {
                format!("{}.{}", current_path, node.label)
            };
            
            if node_path == target_path {
                node.display_name = display_name.to_string();
                return true;
            }
            
            if let Some(children) = &mut node.children {
                if update_node_display_name(children, target_path, display_name, &node_path) {
                    return true;
                }
            }
        }
        false
    }
    
    if update_node_display_name(&mut tree_data, &field_path, &new_display_name, "") {
        Ok(tree_data)
    } else {
        Err(format!("Field path '{}' not found", field_path))
    }
}

pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_opener::init())
        .plugin(tauri_plugin_dialog::init())
        .invoke_handler(tauri::generate_handler![
            parse_crd,
            tree_to_yaml_descriptors,
            parse_yaml_descriptors,
            apply_descriptors_to_tree,
            update_children_descriptor_counts,
            validate_yaml,
            apply_sample_to_fields,
            add_descriptions_to_leaf_nodes,
            save_file_dialog,
            propagate_field_dependency,
            load_crd_from_file,
            save_crd_to_file,
            export_yaml,
            extract_fields_command,
            tree_to_descriptors_command,
            update_tree_with_descriptors_command,
            open_file_dialog,
            update_field_display_name
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
fn main() {
    run();
}
